home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / util / pack / xfdmaster.lha / xfd / Developer / Sources / ASM / Crunch.a < prev    next >
Text File  |  1999-02-05  |  12KB  |  579 lines

  1. * Programmheader
  2. *
  3. *    Name:        Crunch
  4. *    Author:        SDI
  5. *    Distribution:    PD
  6. *    Description:    XFD external decruncher for recognising Crunch1.x
  7. *    Compileropts:    -
  8. *    Linkeropts:    -
  9. *
  10. * 1.0   22.11.98 : first version
  11. * 1.1   09.12.98 : added normal reloc version
  12. * 1.2   11.12.98 : added SEG version
  13. * 1.3   29.12.98 : added BSS hunk support
  14. * 1.4   19.01.99 : added Data scan
  15.  
  16.         INCLUDE    "AINCLUDE:IncDirs.i"
  17.         INCLUDE    "lvo.i"
  18.  
  19.         INCLUDE    "libraries/xfdmaster.i"
  20.         INCLUDE    "exec/memory.i"
  21.         INCLUDE "dos/doshunks.i"
  22.  
  23.         * head function for tests
  24. *        INCLUDE    "xfdExeHead.a"
  25.  
  26. ForeMan        MOVEQ    #-1,D0        ;security
  27.         RTS
  28.  
  29.         DC.L    XFDF_ID
  30.         DC.W    1,0
  31.         DC.L    0,0,S_Crunch
  32.  
  33.         DC.B    "$VER: Crunch 1.4 (19.01.1999) by SDI",0
  34. N_Crunch    DC.B    "Crunch 1.3",0
  35. N_CrunchSeg    DC.B    "Crunch 1.3 Seg",0
  36. N_CrunchData    DC.B    "Crunch 1.3 Data",0
  37.         EVEN
  38.  
  39. S_Crunch    DC.L    S_CrunchSeg    ;next slave
  40.         DC.W    2        ;version
  41.         DC.W    36        ;master version
  42.         DC.L    N_Crunch    ;name
  43.         DC.W    XFDPFF_RELOC
  44.         DC.W    0
  45.         DC.L    RB_Crunch    ;recog buffer
  46.         DC.L    DB_Crunch    ;decrunch buffer
  47.         DC.L    0        ;recog segment
  48.         DC.L    0        ;decrunch segment
  49.         DC.W    0,0
  50.         DC.L    140        ;MinBufSize
  51.  
  52. S_CrunchSeg    DC.L    S_CrunchData    ;next slave
  53.         DC.W    2        ;version
  54.         DC.W    36        ;master version
  55.         DC.L    N_CrunchSeg    ;name
  56.         DC.W    XFDPFF_RELOC
  57.         DC.W    0
  58.         DC.L    RB_CrunchSeg    ;recog buffer
  59.         DC.L    DB_CrunchSeg    ;decrunch buffer
  60.         DC.L    0        ;recog segment
  61.         DC.L    0        ;decrunch segment
  62.         DC.W    0,0
  63.         DC.L    140        ;MinBufSize
  64.  
  65. S_CrunchData    DC.L    0        ;next slaves
  66.         DC.W    2        ;version
  67.         DC.W    38        ;master version
  68.         DC.L    N_CrunchData    ;name
  69.         DC.W    XFDPFF_DATA|XFDPFF_USERTARGET|XFDPFF_RECOGLEN
  70.         DC.W    0
  71.         DC.L    RB_CrunchData    ;recog buffer
  72.         DC.L    DB_CrunchData    ;decrunch buffer
  73.         DC.L    SD_CrunchData    ;recog segment
  74.         DC.L    VD_CrunchData    ;decrunch segment
  75.         DC.W    0,0
  76.         DC.L    12        ;MinBufSize
  77.  
  78. RB_Crunch    MOVEQ    #0,D0
  79.         CMP.L    #$000003F3,(A0)
  80.         BNE.B    .Exit
  81.         MOVE.L    8(A0),D1
  82.         LSL.L    #2,D1
  83.         ADD.L    D1,A0
  84.         CMP.L    #$48E7FFFF,7*4(A0)
  85.         BNE.B    .Exit
  86.         CMP.L    #$70004E96,10*4(A0)
  87.         BNE.B    .Exit
  88.         CMP.L    #$584C4E75,20*4(A0)
  89.         BNE.B    .Exit
  90.         CMP.L    #$000003EB,21*4(A0)
  91.         BNE.B    .Exit
  92.         MOVEQ    #1,D0
  93. .Exit        RTS
  94.  
  95. RB_CrunchSeg    MOVEQ    #0,D0
  96.         CMP.L    #$000003F3,(A0)
  97.         BNE.B    .Exit
  98.         MOVE.L    8(A0),D1
  99.         LSL.L    #2,D1
  100.         ADD.L    D1,A0
  101.         CMP.L    #$48E7FFFF,7*4(A0)
  102.         BNE.B    .Exit
  103.         CMP.L    #$70006146,10*4(A0)
  104.         BNE.B    .Exit
  105.         CMP.L    #$202800AC,20*4(A0)
  106.         BNE.B    .Exit
  107.         CMP.L    #$6712E588,21*4(A0)
  108.         BNE.B    .Exit
  109.         MOVEQ    #1,D0
  110. .Exit        RTS
  111.  
  112. RB_CrunchData    MOVEQ    #0,D0
  113.         CMPI.L    #$43525561,(A0)
  114.         BNE.B    .Exit
  115.         MOVE.L    4(A0),xfdrr_FinalTargetLen(A1)
  116.         MOVE.L    4(A0),xfdrr_MinTargetLen(A1)
  117.         MOVEQ    #1,D0
  118. .Exit        RTS
  119.  
  120. SD_CrunchData    MOVEQ    #0,D0
  121.         CMPI.L    #$43525561,(A0)
  122.         BNE.B    .Exit
  123.         MOVEQ    #1,D0
  124. .Exit        RTS
  125.  
  126. VD_CrunchData    MOVEQ    #12,D1
  127.         ADD.L    8(a0),D1    ;crlen
  128.         CMP.L    D0,D1        ;crlen > buflen ??
  129.         BGT.B    .Exit
  130.         MOVE.L    4(A0),D0
  131.         SUB.L    8(A0),D0    ;cr > uncr ??
  132.         BMI.B    .Exit
  133.         MOVE.L    D1,D0
  134.         RTS
  135. .Exit        MOVEQ    #0,D0
  136.         RTS
  137.  
  138. DB_CrunchSeg    MOVEM.L    D7/A4-A6,-(A7)
  139.         MOVE.L    A0,A5
  140.         MOVE.W    #XFDERR_NOMEMORY,xfdbi_Error(A5)
  141.         MOVE.L    xfdm_ExecBase(A6),A6
  142.         MOVE.L    xfdbi_SourceBuffer(A5),A4
  143.  
  144.         MOVE.L    8(A4),D7
  145.         SUBQ.L    #1,D7        * destination hunk numbers
  146.  
  147.         MOVE.L    A4,A0
  148.         BSR.B    GetCruSegSize
  149.         MOVE.L    D0,xfdbi_TargetBufLen(A5)
  150.         MOVE.L    D0,xfdbi_TargetBufSaveLen(A5)
  151.         MOVE.L    xfdbi_TargetBufMemType(A5),D1
  152.         JSR    _LVOAllocMem(A6)
  153.         MOVE.L    D0,xfdbi_TargetBuffer(A5)
  154.         BEQ.B    .NoMem
  155.  
  156.         MOVE.L    D0,A1
  157.         MOVE.L    A4,A0
  158.         BSR.W    DecrunchCruSeg
  159.  
  160.         CLR.W    xfdbi_Error(A5)
  161.         MOVEQ    #1,D0
  162. .NoMem        MOVEM.L    (A7)+,D7/A4-A6
  163.         RTS
  164.  
  165.         * A0 is buffer
  166.         * D7 is num of hunks
  167. GetCruSegSize    MOVE.L    D6,-(A7)
  168.         MOVE.L    D7,D1
  169.         LSL.L    #2,D1
  170.         MOVE.L    D1,D0
  171.         ADD.L    #$1D0,D1
  172.         LEA    (A0,D1.L),A0    * get first hunk pointer
  173.         ADD.L    #20,D0        * header size
  174.         MOVEQ    #0,D6
  175. .MainLoop    ADD.L    #12,D0        * hunk, size, HUNK_END
  176.         CMP.W    #HUNK_BSS,2(A0)
  177.         BEQ.B    .BSS
  178.         CMP.L    #'CRUa',8(A0)
  179.         BEQ.B    .crunched
  180.         MOVE.L    4(A0),D1
  181.         LSL.L    #2,D1
  182.         ADD.L    D1,D0
  183.         LEA    8(A0,D1.L),A0
  184.         BRA.B    .loopend
  185. .BSS        ADDQ.L    #8,A0
  186.         BRA.B    .loopend
  187. .crunched    ADD.L    12(A0),D0
  188.         MOVE.L    16(A0),D1
  189.         ADDQ.L    #3,D1
  190.         AND.L    #-4,D1
  191.         LEA    20(A0,D1.L),A0
  192. .loopend    BSR.B    .ParseReloc
  193.         ADDQ.L    #1,D6
  194.         CMP.B    D6,D7
  195.         BNE.B    .MainLoop
  196.         MOVE.L    (A7)+,D6
  197.         RTS
  198.  
  199. .ParseReloc    CMP.L    #HUNK_RELOC32,(A0)
  200.         BNE.B    .end
  201.         ADDQ.L    #4,A0
  202.         ADDQ.L    #4,D0        * HUNK_RELOC
  203. .PRLoop        ADDQ.L    #4,D0
  204.         MOVE.L    (A0)+,D1
  205.         BEQ.B    .end
  206.         LSL.L    #2,D1
  207.         ADDQ.L    #4,D1        * related hunk
  208.         LEA    (A0,D1.L),A0
  209.         ADD.L    D1,D0
  210.         BRA.B    .PRLoop
  211. .end        RTS
  212.  
  213.         * A0 is buffer
  214.         * A1 is destination
  215.         * A4 is source buffer
  216.         * D7 is num of hunks
  217. DecrunchCruSeg    MOVEM.L    D2-D6/A2,-(A7)    * hunk size == def size - 512
  218.         MOVE.L    D7,D0        * - reloc space
  219.         LSL.L    #2,D0
  220.         ADD.L    #$1D0,D0
  221.         LEA    (A0,D0.L),A0    * get first hunk pointer
  222.         MOVEQ    #0,D6
  223.         MOVE.L    #HUNK_HEADER,(A1)+
  224.         CLR.L    (A1)+
  225.         MOVE.L    D7,(A1)+    * numhunks
  226.         CLR.L    (A1)+        * starthunk
  227.         MOVE.L    D7,D0
  228.         SUBQ.L    #1,D0
  229.         MOVE.L    D0,(A1)+    * endhunk
  230.         MOVE.L    A1,A2        * start of hunk sizes
  231.         MOVE.L    D7,D0
  232.         LSL.L    #2,D0
  233.         LEA    (A1,D0.L),A1    * skip space
  234. .MainLoop    MOVE.L    (A0)+,(A1)+    * hunk type
  235.         MOVE.L    D6,D0
  236.         LSL.L    #2,D0
  237.         MOVE.L    24(A4,D0.L),D5
  238.         MOVE.L    D5,D4
  239.         AND.L    #$E0000000,D4    * only bits
  240.         AND.L    #$1FFFFFFF,D5    * strip bits
  241.         MOVEQ    #1,D3        * uncrunched
  242.         CMP.W    #HUNK_BSS,-2(A0)
  243.         BEQ.B    .BSS
  244.         CMP.L    #'CRUa',4(A0)
  245.         BEQ.B    .crunched
  246.         MOVE.L    (A0)+,D0
  247.         MOVE.L    D0,(A1)+
  248. .copyhunk    TST.L    D0
  249.         BEQ.B    .loopend
  250.         MOVE.L    (A0)+,(A1)+
  251.         SUBQ.L    #1,D0
  252.         BRA.B    .copyhunk
  253. .BSS        MOVE.L    (A0)+,(A1)+
  254.         BRA.B    .loopend
  255. .crunched    MOVEQ    #0,D3        * crunched
  256.         ADDQ.L    #4,A0
  257.         MOVE.L    4(A0),D0
  258.         LSR.L    #2,D0
  259.         MOVE.L    D0,(A1)+    * store size
  260.         MOVEM.L    A0-A1,-(A7)
  261.         BSR.W    DecrunchCru
  262.         MOVEM.L    (A7)+,A0-A1
  263.         ADD.L    4(A0),A1
  264.         MOVE.L    8(A0),D1
  265.         ADDQ.L    #3,D1
  266.         AND.L    #-4,D1
  267.         LEA    12(A0,D1.L),A0
  268.         SUB.L    #128,D5
  269. .loopend    BSR.B    .CopyReloc
  270.         OR.L    D4,D5        * copy bits
  271.         MOVE.L    D5,(A2)+    * store size
  272.         MOVE.L    #HUNK_END,(A1)+
  273.         ADDQ.L    #1,D6
  274.         CMP.B    D6,D7
  275.         BNE.W    .MainLoop
  276.         MOVEM.L    (A7)+,D2-D6/A2
  277.         RTS
  278.  
  279. .CopyReloc    MOVE.L    A1,D0        * store pointer
  280.         CMP.L    #HUNK_RELOC32,(A0)
  281.         BNE.B    .end
  282.         MOVE.L    (A0)+,(A1)+
  283. .CRLoop        MOVE.L    (A0)+,D1
  284.         MOVE.L    D1,(A1)+
  285.         BEQ.B    .end
  286.         MOVE.L    (A0)+,D2
  287.         SUB.L    D3,D2        * subtract 1, when uncrunched
  288.         MOVE.L    D2,(A1)+    * copy hunkID
  289. .RCLoop        MOVE.L    (A0)+,(A1)+    * copy reloc
  290.         SUBQ.L    #1,D1
  291.         BNE.B    .RCLoop
  292.         BRA.B    .CRLoop
  293. .end        TST.L    D3
  294.         BNE.B    .endR
  295.         MOVE.L    A1,D1    * subtract
  296.         SUB.L    D0,D1    * reloc space
  297.         LSR.L    #2,D1    * from filesize
  298.         SUB.L    D1,D5
  299. .endR        RTS
  300.  
  301. DB_Crunch    MOVEM.L    D5-D7/A2-A6,-(A7)
  302.         MOVE.L    A0,A5
  303.         MOVEQ    #0,D6                * return value
  304.         MOVE.W    #XFDERR_NOMEMORY,xfdbi_Error(A5)
  305.         MOVE.L    xfdm_ExecBase(A6),A6
  306.         MOVE.L    xfdbi_SourceBuffer(A5),A4
  307.  
  308.         MOVE.L    8(A4),D7
  309.         SUBQ.L    #3,D7        * destination hunk numbers
  310.  
  311.         MOVE.L    D7,D1
  312.         LSL.L    #2,D1
  313.         MOVE.L    D1,D0
  314.         LSL.L    #1,D0
  315.         ADD.L    D1,D0    * multiply with 12
  316.         ADD.L    #$1E4,D0
  317.  
  318.         LEA.L    (A4,D0.L),A2
  319.         MOVE.L    4(A2),D5
  320.         MOVE.L    D5,D0
  321.         MOVEQ    #0,D1
  322.         JSR    _LVOAllocMem(A6)
  323.         TST.L    D0
  324.         BEQ.B    .NoMem
  325.         MOVE.L    D0,A3
  326.         
  327.         MOVE.L    D0,A1
  328.         MOVE.L    A2,A0
  329.         BSR.W    DecrunchCru
  330.  
  331.         MOVE.L    A3,A0
  332.         BSR.W    CountCruSize
  333.  
  334.         MOVE.L    D0,xfdbi_TargetBufLen(A5)
  335.         MOVE.L    D0,xfdbi_TargetBufSaveLen(A5)
  336.         MOVE.L    xfdbi_TargetBufMemType(A5),D1
  337.         JSR    _LVOAllocMem(A6)
  338.         MOVE.L    D0,xfdbi_TargetBuffer(A5)
  339.         BEQ.B    .NoMem2
  340.  
  341.         MOVEA.L    A3,A0
  342.         MOVEA.L    D0,A1
  343.         BSR.W    MakeCruFile
  344.  
  345.         CLR.W    xfdbi_Error(A5)
  346.         MOVEQ    #1,D6                * set true
  347. .NoMem2        MOVE.L    D5,D0
  348.         MOVE.L    A3,A1
  349.         JSR    _LVOFreeMem(A6)
  350. .NoMem        MOVE.L    D6,D0
  351.         MOVEM.L    (A7)+,D5-D7/A2-A6
  352.         RTS
  353.  
  354. DB_CrunchData    MOVEM.L    A4-A6,-(A7)
  355.         MOVE.L    A0,A5
  356.         MOVE.L    xfdm_ExecBase(A6),A6
  357.         MOVE.L    xfdbi_SourceBuffer(A5),A4
  358.  
  359.         MOVE.W    #XFDERR_NOMEMORY,xfdbi_Error(A5)
  360.         MOVE.L    4(A4),D0
  361.         MOVE.L    xfdbi_UserTargetBuf(A5),A1
  362.         MOVE.L    D0,xfdbi_TargetBufSaveLen(A5)
  363.  
  364.         BTST.B    #XFDFB_USERTARGET,1+xfdbi_Flags(A5)
  365.         BNE.B    .Decrunch
  366.  
  367.         MOVE.L    D0,xfdbi_TargetBufLen(A5)
  368.         MOVE.L    xfdbi_TargetBufMemType(A5),D1
  369.         JSR    _LVOAllocMem(A6)
  370.         MOVE.L    D0,xfdbi_TargetBuffer(A5)
  371.         BEQ.B    .End
  372.         MOVE.L    D0,A1
  373. .Decrunch    MOVEA.L    A4,A0
  374.         BSR.B    DecrunchCru
  375.         CLR.W    xfdbi_Error(A5)
  376.         MOVEQ    #1,D0
  377. .End        MOVEM.L    (A7)+,A4-A6
  378.         RTS
  379.  
  380. DecrunchCru    MOVEM.L    D2-D6/A2-A4,-(A7)
  381.         MOVEA.L    A1,A2
  382.         ADDA.L    4(A0),A1
  383.         ADDQ.W    #8,A0
  384.         ADDA.L    (A0)+,A0
  385.         LEA    Sub1(PC),A3
  386.         MOVEQ    #8,D5
  387.         MOVE.W    #$00FF,D6
  388.         MOVE.B    -(A0),D4
  389. .Dec1        CMPA.L    A1,A2
  390.         BCS.B    .Dec2
  391.         MOVEM.L    (A7)+,D2-D6/A2-A4
  392.         RTS
  393.  
  394. .Dec2        JSR    (A3)
  395.         BCS.B    .Dec3
  396.         MOVE.B    -(A0),-(A1)
  397.         BRA.B    .Dec1
  398. .Dec3        MOVEQ    #0,D0
  399.         MOVEQ    #0,D1
  400.         MOVEQ    #0,D2
  401.         JSR    (A3)
  402.         BCC.B    .Dec4
  403.         MOVEQ    #0,D1
  404.         MOVEQ    #2,D2
  405.         JSR    (A3)
  406.         BCC.B    .Dec4
  407.         MOVEQ    #1,D1
  408.         MOVEQ    #4,D2
  409.         JSR    (A3)
  410.         BCC.B    .Dec4
  411.         MOVEQ    #1,D1
  412.         MOVEQ    #8,D2
  413.         JSR    (A3)
  414.         BCC.B    .Dec4
  415.         MOVEQ    #2,D1
  416.         MOVEQ    #$000C,D2
  417.         JSR    (A3)
  418.         BCC.B    .Dec4
  419.         MOVEQ    #$0014,D2
  420.         MOVE.B    -(A0),D0
  421.         CMP.B    D6,D0
  422.         BNE.B    .Dec5
  423.         ADD.W    D0,D2
  424.         MOVE.B    -(A0),D0
  425.         ROR.W    #8,D0
  426.         MOVE.B    -(A0),D0
  427.         BRA.B    .Dec5
  428. .Dec4        JSR    (A3)
  429.         ADDX.B    D0,D0
  430.         DBRA    D1,.Dec4
  431. .Dec5        ADD.W    D0,D2
  432.         BNE.B    .Dec6
  433.         MOVEQ    #$0010,D1
  434.         JSR    (A3)
  435.         BCC.B    .Dec7
  436.         MOVEQ    #$0014,D1
  437.         JSR    (A3)
  438.         BCC.B    .Dec7
  439.         MOVEQ    #$0018,D1
  440.         JSR    (A3)
  441.         BCC.B    .Dec7
  442.         MOVEQ    #$001C,D1
  443.         BRA.B    .Dec7
  444. .Dec6        MOVEQ    #0,D1
  445.         JSR    (A3)
  446.         ADDX.B    D1,D1
  447.         JSR    (A3)
  448.         ADDX.B    D1,D1
  449.         LSL.B    #2,D1
  450. .Dec7        MOVEM.W    $A(A3,D1.W),D0/A4    * access data field, A3 points
  451.         MOVEQ    #0,D3            * to Sub1, which is $A bytes
  452.         CMP.W    D5,D0
  453.         BCS.B    .Dec8
  454.         MOVE.B    -(A0),D3
  455.         SUBQ.W    #8,D0
  456. .Dec8        JSR    (A3)
  457.         ADDX.W    D3,D3
  458.         DBRA    D0,.Dec8
  459.         ADDA.L    D3,A4
  460.         ADDA.L    A1,A4
  461.         MOVE.B    (A4),-(A1)
  462. .Dec9        MOVE.B    -(A4),-(A1)
  463.         DBRA    D2,.Dec9
  464.         BRA.W    .Dec1
  465.  
  466. Sub1        ADD.B    D4,D4
  467.         BNE.B    .SubEnd
  468.         MOVE.B    -(A0),D4
  469.         ADDX.B    D4,D4
  470. .SubEnd        RTS
  471.         DC.W    06,$0000,09,$0080,12,$0480,13,$2480,05,$0000
  472.         DC.W    06,$0040,06,$00C0,06,$0140
  473.  
  474.  
  475.         * A0 is buffer
  476.         * D7 is num of hunks
  477. CountCruSize    MOVEM.L    D2/D6,-(A7)
  478.         MOVE.L    D7,D0
  479.         LSL.L    #4,D0        * size, HUNK_CODE, size, HUNK_END --> 4*4 bytes
  480.         ADD.L    #20,D0        * header hunk
  481.         MOVEQ    #0,D6        * hunk counter
  482. .MainLoop    MOVE.L    (A0)+,D1
  483.         MOVE.L    D1,D2
  484.         ANDI.L    #-4,D1        * last bits are CHIP/RELOC markers
  485.         ADD.L    D1,D0        * add that size
  486.         LEA    (A0,D1.L),A0    * skip that part
  487.         BTST    #1,D2        * no reloc hunks
  488.         BEQ.B    .LoopEnd
  489.         ADDQ.L    #4,D0        * place for HUNK_RELOC32
  490. .Reloc        MOVE.W    (A0)+,D1
  491.         ADDQ.L    #4,D0    * add size or empty place for last marker
  492.         TST.W    D1
  493.         BEQ.B    .LoopEnd
  494.         ADDQ.L    #8,D0        * add related hunk and first reloc
  495.         ADDQ.L    #6,A0
  496.         SUBQ.W    #2,D1
  497.         BMI.B    .Reloc
  498. .RelLoop    ADDQ.L    #4,D0
  499.         MOVE.W    (A0)+,D2    * normally we have word offsets
  500.         BNE.B    .Skip
  501.         MOVE.L    (A0)+,D2    * skip LONG offset
  502. .Skip        DBRA.B    D1,.RelLoop
  503.         BRA.B    .Reloc
  504. .LoopEnd    ADDQ.L    #1,D6        * next hunk
  505.         CMP.L    D6,D7
  506.         BNE.B    .MainLoop
  507.         MOVEM.L    (A7)+,D2/D6
  508.         RTS
  509.  
  510.         * A0 is buffer
  511.         * A1 is destination
  512.         * A4 is source file (crunched)
  513.         * D7 is num of hunks
  514. MakeCruFile    MOVEM.L    D2/D6/A4,-(A7)
  515.         MOVE.L    #HUNK_HEADER,(A1)+
  516.         CLR.L    (A1)+
  517.         MOVE.L    D7,(A1)+    * numhunks
  518.         CLR.L    (A1)+        * starthunk
  519.         MOVE.L    D7,D0
  520.         SUBQ.L    #1,D0
  521.         MOVE.L    D0,(A1)+    * endhunk
  522.         LEA    24(A4),A4    * start of sizes
  523. .HeadLoop    MOVE.L    (A4)+,(A1)+    * copy sizes
  524.         DBRA    D0,.HeadLoop
  525.  
  526.         MOVEQ    #0,D6
  527. .MainLoop    MOVE.L    (A0)+,D1
  528.         MOVE.L    D1,D2
  529.         LSR.L    #2,D1
  530.         BEQ.B    .BSS
  531.         MOVE.L    #HUNK_CODE,D0
  532.         BTST    #0,D2
  533.         BEQ.B    .Next
  534.         MOVE.L    #HUNK_DATA,D0
  535. .Next        MOVE.L    D0,(A1)+
  536.         MOVE.L    D1,(A1)+
  537.         BEQ.B    .DoRel
  538.         BRA.B    .CopyHunk
  539. .BSS        MOVE.L    #HUNK_BSS,(A1)+
  540.         MOVE.L    D6,D0
  541.         SUB.L    D7,D0
  542.         LSL.L    #2,D0
  543.         MOVE.L    (A4,D0.L),(A1)+
  544.         BRA.B    .DoRel
  545. .CopyHunk    MOVE.L    (A0)+,(A1)+
  546.         SUBQ.L    #1,D1
  547.         BNE.B    .CopyHunk
  548. .DoRel        BTST    #1,D2
  549.         BEQ.B    .LoopEnd
  550.         MOVE.L    #HUNK_RELOC32,(A1)+
  551. .Reloc        MOVEQ    #0,D1
  552.         MOVE.W    (A0)+,D1    * copy size
  553.         MOVE.L    D1,(A1)+
  554.         BEQ.B    .LoopEnd
  555.         MOVEQ    #0,D0
  556.         MOVE.W    (A0)+,D0
  557.         MOVE.L    D0,(A1)+    * move hunknum
  558.         MOVEQ    #0,D3
  559.         MOVE.L    (A0)+,D3
  560.         MOVE.L    D3,(A1)+
  561.         SUBQ.W    #2,D1
  562.         BMI.B    .Reloc
  563. .RelLoop    MOVEQ    #0,D0
  564.         MOVE.W    (A0)+,D0
  565.         BNE.B    .Skip
  566.         MOVE.L    (A0)+,D0
  567. .Skip        ADD.L    D0,D3
  568.         MOVE.L    D3,(A1)+
  569.         DBRA    D1,.RelLoop
  570.         BRA.B    .Reloc
  571.  
  572. .LoopEnd    MOVE.L    #HUNK_END,(A1)+
  573.         ADDQ.W    #1,D6
  574.         CMP.W    D6,D7
  575.         BNE.B    .MainLoop
  576.         MOVEM.L    (A7)+,D2/D6/A4
  577.         RTS
  578.         END
  579.